<template>
  <div style="position: relative;">
    <div :class="{avatar_wrap: !multiple}">
      <div v-if="!multiple && image.url" class="avatar_mask">
        <div class="icon_wrap">
          <i @click="previewImg" class="el-icon-zoom-in"></i>
          <i @click="changeImg" class="el-icon-refresh"></i>
          <i @click="deleteImg" class="el-icon-delete"></i>
        </div>
      </div>
      <el-upload
        :headers="{
          'Authorization': token
        }"
        ref="avatar"
        :class="['upload_wrap', {'photo-wall': multiple}]"
        action="/api/userSystem/Common/Files"
        :list-type="multiple ? 'picture-card' : 'text'"
        :limit="multiple ? limit : 0"
        :on-exceed="handleExceed"
        :on-preview="handlePreview"
        :show-file-list="multiple"
        :on-success="handleAvatarSuccess"
        :on-remove="handleRemove"
        :before-remove="beforeRemove"
        :before-upload="beforeAvatarUpload"
        :file-list="files"
        multiple
      >
        <el-button class="upload_focus" ref="uploadFocus"></el-button>
        <i v-if="multiple" class="el-icon-plus"></i>
        <template v-else>
          <img v-if="image.url" :src="image.url" />
          <i v-else class="el-icon-plus avatar-uploader-icon"></i>
        </template>
      </el-upload>
    </div>
    <span
      slot="tip"
      :class="{ single_file_tip: !multiple, multiple_file_tip: multiple }"
      :style="{ 'max-width': tipWidth }"
    >
      {{ tip }}
    </span>
  </div>
</template>

<script>
import { getTmpCache } from '@u/cache.js';
import { typeOf } from '@u/common.js';

export default {
  name: 'PhotoUpload',
  props: {
    fileList: {
      type: [Object, Array],
      default: () => []
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    limit: {
      type: Number,
      default: 5,
    },
    imgSize: {
      type: Number,
      default: 2,
    },
    img: {
      type: Object,
      default: () => {
        return {
          type: 'jpg/jpeg/png',
          msg: '上传图片只能是 jpg/jpeg/png 格式！'
        };
      },
    },
    tip: {
      type: String,
      default: '请上传小于等于2M的图片\n支持扩展名：.jpg .jpeg .png',
    },
    tipWidth: {
      type: String,
      default: '200px',
    }
  },
  watch: {
    fileList: {
      handler(newVal) {
        if (typeOf(newVal) == 'object') {
          this.image = this.$deepCopy(newVal);
        }
        if (typeOf(newVal) == 'array') {
          this.files = this.$deepCopy(newVal);
        }
      },
      deep: true,
      immediate: true,
    }
  },
  data() {
    return {
      token: getTmpCache('token'),
      image: {
        id: 0,
        name: '',
        url: '',
      },
      files: [],
      isPass: true
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.$el.querySelector('input').addEventListener('click', () => {
        this.doFocus();
      });
    });
  },
  methods: {
    doFocus() {
      this.$refs.uploadFocus.$el.focus(); // 重新聚焦
    },
    changeImg() { // 重新上传单个文件
      this.doFocus();
      this.$refs.avatar.$el.querySelector('input').click();
    },
    deleteImg() { // 删除上传的单个文件
      this.$confirm(`确定移除 ${ this.image.name }？`).then(() => {
        this.doFocus();
        this.$emit('remove', this.image);
        this.image = {
          id: 0,
          name: '',
          url: ''
        };
      }).catch(() => {});
    },
    previewImg() { // 查看上传的单个文件
      window.open(this.image.url);
      this.$emit('preview', this.image);
    },
    handleAvatarSuccess(res) {
      if (res.code == 200) {
        this.$message.success('上传成功');
        this.image = res.data;
        this.$emit('success', res.data);
      } else {
        this.$message.error(res.message);
      }
    },
    handleExceed() { // 超出上传个数
      this.$message.warning(`只能上传${ this.limit }张图片！`);
    },
    beforeRemove(file) { // 移除某个文件之前
      if (this.isPass) {
        return this.$confirm(`确定移除 ${ file.name }？`, '取消确认');
      } else {
        this.isPass = true;
      }
    },
    handleRemove(file) { // 移除某个文件回调
      let obj;
      if (!file.response) {
        obj = {
          id: file.id,
          name: file.name,
          url: file.url
        };
      } else {
        obj = file.response.data;
      }
      this.$emit('remove', obj);
    },
    handlePreview(file) { // 点击预览某个文件
      let obj;
      if (!file.response) {
        obj = {
          id: file.id,
          name: file.name,
          url: file.url
        };
      } else {
        obj = file.response.data;
      }
      window.open(obj.url);
      this.$emit('preview', obj);
    },
    beforeAvatarUpload(file) {
      const names = file.name.split('.'),
        isSize = file.size / 1024 / 1024 < this.imgSize;
      let isType = true;
      if (this.img.type != 'all') {
        isType = false;
        if (names.length && this.img.type.includes(names[names.length - 1])) {
          isType = true;
        }
      }
      this.isPass = isType && isSize;
      if (!isType) {
        this.$message.error(this.img.msg);
        return this.isPass;
      }
      if (!isSize) {
        this.$message.error(`上传图片大小不能超过${ this.imgSize }MB！`);
        return this.isPass;
      }
      return this.isPass;
    }
  }
};
</script>

<style lang="scss" scoped>
.upload_focus {
  width: 100%;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  background: transparent !important;
  border-radius: 6px;
  border: 2px dashed #d9d9d9;
}
.upload_wrap {
  width: inherit;
  height: inherit;
  &::v-deep .el-upload {
    position: relative;
    border: 0;
    &:focus {
      border-color: #d9d9d9 !important;
    }
  }
}
.avatar_wrap {
  position: relative;
  width: 120px;
  height: 120px;
  line-height: 120px;
  &:hover {
    .avatar_mask {
      display: block;
    }
  }
  .avatar_mask {
    display: none;
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    border-radius: 6px;
    background: rgba(0, 0, 0, 0.4);
    background-position: 10px 10px;
    color: #ffffff;
    z-index: 10;
    &:hover + .upload_wrap {
      .upload_focus {
        border-color: $themeColor_IE;
        border-color: $themeColor;
      }
    }
    .icon_wrap {
      text-align: center;
      i {
        font-size: 20px;
        margin: 4px;
        cursor: pointer;
      }
    }
  }
  ::v-deep {
    .el-upload {
      width: inherit;
      height: inherit;
      img {
        width: inherit;
        height: inherit;
      }
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
      .avatar-uploader-icon {
        width: inherit;
        height: inherit;
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 28px;
        color: #8c939d;
      }
    }
  }
}
.photo-wall {
  margin-top: -10px;
  ::v-deep {
    .el-upload.el-upload--picture-card {
      line-height: 120px;
      margin-top: 10px;
    }
    .el-upload-list.el-upload-list--picture-card {
      line-height: 0;
    }
    .el-upload.el-upload--picture-card,
    .el-upload-list--picture-card .el-upload-list__item {
      width: 120px;
      height: 120px;
      margin-top: 10px;
      margin-bottom: 0;
    }
    .el-icon-close-tip {
      display: none !important;
    }
    .el-icon-zoom-in, .el-icon-delete {
      font-size: 20px !important;
    }
  }
}
.single_file_tip {
  white-space: pre-line;
  line-height: 20px;
  position: absolute;
  bottom: 0;
  left: 130px;
}
.multiple_file_tip {
  display: block;
  margin-top: 8px;
}
</style>
